# coding:utf-8

import requests
import pandas as pd
import random
import time
from datetime import datetime

# 随机请求头列表
USER_AGENTS = [
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
    "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36",
    "Mozilla/5.0 (Windows NT 10.0; rv:89.0) Gecko/20100101 Firefox/89.0"
]

# 在文件顶部添加导入
import io

def get_sina_historical_exchange_rate(currency_pair, start_date, end_date, retry=3):
    """
    获取新浪财经的历史汇率数据（优化版）
    
    :param currency_pair: 货币对，例如 'USDCNY'
    :param start_date: 开始日期 'YYYY-MM-DD'
    :param end_date: 结束日期 'YYYY-MM-DD'
    :param retry: 重试次数，默认3次
    :return: 包含历史汇率数据的 DataFrame
    """
    # 验证日期有效性
    try:
        start = datetime.strptime(start_date, '%Y-%m-%d')
        end = datetime.strptime(end_date, '%Y-%m-%d')
        if start > end:
            print("错误：开始日期不能晚于结束日期")
            return None
    except ValueError:
        print("日期格式错误，请使用YYYY-MM-DD格式")
        return None

    url = f"http://biz.finance.sina.com.cn/forex/forex.php?mod=history&startdate={start_date}&enddate={end_date}&symbol={currency_pair}&type=0"
    
    for attempt in range(retry):
        try:
            # 随机延迟（1-3秒）
            time.sleep(random.uniform(1, 3))
            
            headers = {
                "User-Agent": random.choice(USER_AGENTS),
                "Accept-Language": "zh-CN,zh;q=0.9",
                "Accept-Encoding": "gzip, deflate"
            }
            
            response = requests.get(url, headers=headers, timeout=10)
            response.encoding = 'gb2312'
            
            if response.status_code == 200:
                tables = pd.read_html(io.StringIO(response.text))
                
                if tables:
                    df = tables[0]
                    # 增强表头处理逻辑
                    if len(df) > 1 and df.iloc[0].notnull().all():
                        df.columns = df.iloc[0]
                        df = df[1:].reset_index(drop=True)
                    else:
                        print("检测到异常表头结构")
                        print("原始表格前两行：")
                        print(df.head(2))
                        return None
                    
                    # 增强数据有效性检查
                    required_columns = ['日期', '开盘价', '收盘价']
                    if not df.empty and all(col in df.columns for col in required_columns):
                        # 转换日期格式
                        df['日期'] = pd.to_datetime(df['日期'], errors='coerce')
                        df = df.dropna(subset=['日期'])
                        return df
                    else:
                        print(f"缺少必要字段，实际字段: {df.columns.tolist()}")
                else:
                    print("未找到有效表格数据，响应内容前500字符：")
                    print(response.text[:500])
            else:
                print(f"请求失败，状态码: {response.status_code}")

        except Exception as e:
            print(f"第{attempt+1}次尝试失败，错误信息: {str(e)}")
            if attempt == retry - 1:
                return None

    return None

# 备用API示例（需要申请权限）
"https://stock.finance.sina.com.cn/forex/api/openapi.php/ForexService.getDayK?symbol={currency_pair}"

if __name__ == '__main__':
    # 示例使用当前年份数据（注意：不要使用未来日期）
    df = get_sina_historical_exchange_rate('USDCNY', '2023-01-01', '2023-12-31')
    
    if df is not None and not df.empty:
        print("成功获取数据：")
        print(df.head())
    else:
        print("未能获取有效数据，请检查：")
        print("1. 货币对是否正确（如USDCNY）")
        print("2. 日期范围是否有效（不要使用未来日期）")
        print("3. 网络连接是否正常")